/**
 * 
 */
package gui.view;

import interfaces.IMeasure;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import massDistribution.MeasuredAttribute;
import stubs.ServiceStub;
import engine.ExternalSource;
import engine.Service;

/**
 * @author Elisa Costante
 * 
 */
public class InputPanel extends javax.swing.JPanel {

	private static final long serialVersionUID = -5807361589324668548L;
	private int numberOfPanels;
	private ArrayList<JPanel> allPanel;

	private ArrayList<ExternalSource> sourceList;
	private ArrayList<MeasuredAttribute> allAttributes;
	private ActionListener listener;
	private JButton generateButton;
	private JButton okButton;
	private JPanel dataPanel;
	private JPanel buttonsPanel;
	private ArrayList<JTable> jtableList;

	public InputPanel(ArrayList<ExternalSource> sourcesList,
			ArrayList<MeasuredAttribute> allAttributesToShow,
			ActionListener listener) {
		super();
		this.allAttributes = allAttributesToShow;
		this.sourceList = sourcesList;
		this.numberOfPanels = sourcesList.size();
		this.listener = listener;
		this.allPanel = new ArrayList<JPanel>(numberOfPanels);
		this.setBackground(CustomizedColor.BACK_GROUND_COLOR);

		jtableList = new ArrayList<JTable>();

		setDataPanel(sourceList);
		setDataPanelLayout();

		setButtons();
		setButtonsPanelLayout();

		setMainLayout();
	}

	/**
	 * 
	 */
	private void setButtonsPanelLayout() {
		buttonsPanel = new JPanel();

		GroupLayout layout = new GroupLayout(buttonsPanel);
		buttonsPanel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		SequentialGroup horizontal = layout.createSequentialGroup();
		horizontal.addComponent(generateButton, 100, 100, 100);
		horizontal.addComponent(okButton, 100, 100, 100);

		ParallelGroup vertical = layout.createParallelGroup(Alignment.CENTER);
		vertical.addComponent(generateButton, 30, 30, 30);
		vertical.addComponent(okButton, 30, 30, 30);

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);
	}

	/**
	 * 
	 */
	private void setMainLayout() {

		GroupLayout layout = new GroupLayout(this);
		this.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		ParallelGroup horizontal = layout.createParallelGroup(Alignment.CENTER);
		JScrollPane scrollPane = new JScrollPane(dataPanel);
		horizontal.addComponent(scrollPane, 100, 100, Short.MAX_VALUE);
		horizontal.addComponent(buttonsPanel, 100, 100, Short.MAX_VALUE);

		SequentialGroup vertical = layout.createSequentialGroup();
		vertical.addComponent(scrollPane, 100, 100, Short.MAX_VALUE);
		vertical.addComponent(buttonsPanel, 50, 50, 50);

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);

	}

	/**
	 * 
	 */
	private void setDataPanelLayout() {
		dataPanel = new JPanel();

		GroupLayout layout = new GroupLayout(dataPanel);
		dataPanel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		ParallelGroup horizontal = layout.createParallelGroup(Alignment.CENTER);
		SequentialGroup vertical = layout.createSequentialGroup();

		for (int i = 0; i < allPanel.size(); i++) {
			JScrollPane panelScroll = new JScrollPane(allPanel.get(i));

			horizontal.addComponent(panelScroll, 100, 100, Short.MAX_VALUE);
			vertical.addComponent(panelScroll, 80, 100, Short.MAX_VALUE);

		}

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);

	}

	/**
	 * 
	 */
	private void setButtons() {
		generateButton = new JButton("Generate");
		generateButton.setActionCommand("generate");
		generateButton.addActionListener(listener);
		generateButton.setBackground(CustomizedColor.GENERATE_BUTTON_COLOR);

		okButton = new JButton("ok");
		okButton.setActionCommand("okInputPanel");
		okButton.addActionListener(listener);
		okButton.setBackground(CustomizedColor.GENERATE_BUTTON_COLOR);
	}

	/**
	 * @param sourceList
	 * 
	 */
	public void setDataPanel(ArrayList<ExternalSource> sourceList) {

		for (int i = 0; i < numberOfPanels; i++) {
			allPanel.add(setPanel(sourceList.get(i)));
		}

	}

	/**
	 * @param iSource
	 * @return
	 */
	private JPanel setPanel(ExternalSource source) {
		JPanel panel = new JPanel();
		panel.setBackground(CustomizedColor.WHITE);

		Border border = BorderFactory.createLineBorder(Color.gray);
		border = BorderFactory.createTitledBorder(border, source
				.getIdentifierName(), TitledBorder.CENTER, TitledBorder.CENTER);
		panel.setBorder(border);

		JTable inputTable = getInputTable(source);
		JScrollPane scroll = new JScrollPane(inputTable);
		inputTable.setFillsViewportHeight(true);

		setPanelLayout(panel, scroll);

		return panel;
	}

	/**
	 * @param panel
	 * @param scroll
	 */
	private void setPanelLayout(JPanel panel, JScrollPane scroll) {
		GroupLayout layout = new GroupLayout(panel);
		panel.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);

		ParallelGroup horizontal = layout.createParallelGroup(Alignment.CENTER);
		horizontal.addComponent(scroll, 100, 100, Short.MAX_VALUE);

		SequentialGroup vertical = layout.createSequentialGroup();
		vertical.addComponent(scroll, 80, 100, Short.MAX_VALUE);

		layout.setHorizontalGroup(horizontal);
		layout.setVerticalGroup(vertical);
	}

	public void refreshDataModel(ArrayList<ExternalSource> sourcesList) {
		if (sourcesList != null && jtableList != null
				&& sourcesList.size() == jtableList.size()) {
			for (int i = 0; i < sourcesList.size(); i++) {
				JTable jtable = jtableList.get(i);
				DefaultTableModel tableModel = new MyTableModel(sourcesList
						.get(i));
				jtable.setModel(tableModel);
			}
		}
	}

	/**
	 * @param string
	 * @param measuredAttributes
	 * @param monitoredServices
	 * @return
	 */
	private JTable getInputTable(ExternalSource source) {
		DefaultTableModel tableModel = new MyTableModel(source);
		JTable jtable = new JTable(tableModel);
		MyCustomTableCellRenderer reputationRenderer = new MyCustomTableCellRenderer();
		jtable.setDefaultRenderer(String.class, reputationRenderer);
		jtableList.add(jtable);
		return jtable;
	}

	private class MyTableModel extends DefaultTableModel {

		private static final long serialVersionUID = 2752107663606437639L;
		private ExternalSource source;
		private ArrayList<Service> allServices;

		public MyTableModel(ExternalSource source) {
			super();
			this.source = source;
			allServices = this.source.getMeasuredServices();
			setcolumns();
			setrows();
			setTableData();
		}

		/**
		 * 
		 */
		private void setrows() {
			if (allAttributes != null && allServices != null) {
				int rowCount = allServices.size();
				this.setRowCount(rowCount);

				if (rowCount > 0) {
					int i = 0;
					for (Service service : allServices) {
						setValueAt(service.getIdentifierName(), i, 0);
						i++;
					}

				}
			}

		}

		/**
		 * 
		 */
		private void setcolumns() {
			if (allAttributes != null) {
				this.setColumnCount(allAttributes.size() + 1);
				// Set Column NAmes
				String[] columnNames = new String[allAttributes.size() + 1];
				columnNames[0] = "";
				for (int i = 0; i < allAttributes.size(); i++) {
					columnNames[i + 1] = allAttributes.get(i).getIdentifier();
				}
				this.setColumnIdentifiers(columnNames);

			}

		}

		/**
		 * 
		 */
		private void setTableData() {
			ArrayList<Service> monitoredServices = source.getMeasuredServices();
			if (monitoredServices != null) {
				for (int i = 0; i < getRowCount(); i++) {

					String serviceRowName = (String) this.getValueAt(i, 0);
					if (source.getMeasuredService(serviceRowName) != null) {
						// The source has values for the services
						ServiceStub service = (ServiceStub) source
								.getMeasuredService(serviceRowName);
						// gets the attributeMeasured from the source
						ArrayList<MeasuredAttribute> measuredAttributes = service
								.getMeasuredAttributes();
						// controlla le colonne
						for (int j = 0; j < getColumnCount() - 1; j++) {

							MeasuredAttribute attribute = (MeasuredAttribute) allAttributes
									.get(j);

							if (measuredAttributes.contains(attribute)) {
								// Set the measured value for the attribute

								int indexOfAttribute = measuredAttributes
										.indexOf(attribute);
								IMeasure value = measuredAttributes.get(
										indexOfAttribute).getMetric()
										.getMeasure();
								if (value != null)
									this.setValueAt(value.toString(), i, j + 1);
								else {
									this.setValueAt("", i, j + 1);

								}
							} else {
								// il servizio non misura questo attributo
								setValueAt("NOT_MEASURED", i, j + 1);
							}

						}
					}

				}
			}
		}

		public Class getColumnClass(int column) {
			return String.class;
		}
	}

	private class MyCustomTableCellRenderer extends DefaultTableCellRenderer {

		private static final long serialVersionUID = -4395389534866530636L;

		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int column) {
			Component cell = super.getTableCellRendererComponent(table, value,
					isSelected, hasFocus, row, column);

			if ((value instanceof String)
					&& (((String) value).equalsIgnoreCase("NOT_MEASURED") || ((String) value)
							.equalsIgnoreCase(""))) {
				cell.setBackground(CustomizedColor.OVERLIGHT_GRAY);
				cell.setForeground(Color.black);
			} else {
				cell.setBackground(Color.white);
				cell.setForeground(Color.black);
			}
			return cell;
		}
	}
}
